/*
 * Copyright (c) 2009, Hamish Morgan
 * All rights reserver.
 */
package locusts.common.behaviours;

import java.util.List;

import javax.vecmath.Vector2d;
import locusts.common.entities.Flock;
import locusts.common.entities.Vehicle;

/**
 * Steerin to avoid collision with neighbouring boids.
 * 
 * @author Hamish Morgan
 */
public class FlockSeparationBehaviour extends AbstractFlockBehaviour {
    
    private static final double DEFAULT_SEPARATION_GRAVITY = -100d;
    protected double gravity;
    
    public FlockSeparationBehaviour(double weight, Flock boids,
            double minDistance, double maxDistance, double maxAngle,
            double gravity) {
        super(weight, boids, minDistance, maxDistance, maxAngle);
        setGravity(gravity);
    }
    
    public FlockSeparationBehaviour(double weight, Flock boids,
            double minDistance, double maxDistance, double maxAngle) {
        this(weight, boids, minDistance, maxDistance, maxAngle,
                DEFAULT_SEPARATION_GRAVITY);
    }
    
    public void setGravity(double gravity) {
        if (Double.isInfinite(gravity) || Double.isNaN(gravity))
            throw new IllegalArgumentException();
        this.gravity = gravity;
    }
    
    // Separation: steer to avoid crowding local flockmates
    public Vector2d getSteering(final Vehicle boid) {
        
        final Vector2d steering = new Vector2d();
        List<Vehicle> neighbors = getNeighbors(boid);
        
        if (neighbors.size() == 0)
            return steering;
        if (getWeight() == 0d)
            return steering;
        
        for (Vehicle other : neighbors) {
            if (other.position.x != boid.position.x)
                steering.x += gravity / (other.position.x - boid.position.x);
            if (other.position.y != boid.position.y)
                steering.y += gravity / (other.position.y - boid.position.y);
        }
        steering.scale(1d / neighbors.size());
        
        steering.scale(getWeight());
        return steering;
    }
    
}